package com.ruoyi.framework.swagger;

import cn.hutool.core.util.StrUtil;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RestController;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.ApiKey;
import springfox.documentation.service.Contact;
import springfox.documentation.service.SecurityScheme;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;

/**
 * @Description <文件描述>
 * @Author Jak
 * @Date 2021/3/2 14:25
 * @Version: V1.0
 * @Modified:
 */
@Slf4j
@ConditionalOnProperty(prefix = "app.swagger", name = "enabled", havingValue = "true")
@Component
public class SwaggerDocketRegistrar implements BeanFactoryAware {
    @Autowired
    private SwaggerProperties swaggerProperties;

    @Autowired
    private Environment environment;

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        DefaultListableBeanFactory listableBeanFactory = (DefaultListableBeanFactory)beanFactory;

        if (swaggerProperties.getPackages() != null && swaggerProperties.getPackages().size() > 0) {
            for (SwaggerProperties.PackageInfo info : swaggerProperties.getPackages()) {
                Docket docket = new Docket(DocumentationType.SWAGGER_2)
                        .apiInfo(apiInfo(info.getName(),""))
                        .groupName(info.getName())
                        .select()
                        .apis(RequestHandlerSelectors.basePackage(info.getPack()))
                        //加了ApiOperation注解的类，才生成接口文档
                        .apis(RequestHandlerSelectors.withClassAnnotation(RestController.class))
                        .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
                        .paths(PathSelectors.any())
                        .build();
                listableBeanFactory.registerSingleton(info.getPack()+".Docket", docket);
                log.info("\nWeb starter -- 添加了 swagger 扫描路径：{}", info.getName() + ":" + info.getPack());
            }
        } else {
            Docket docket = new Docket(DocumentationType.SWAGGER_2)
                    .apiInfo(apiInfo("xxx",""))
                    .groupName("默认分组")
                    .select()
                    .apis(RequestHandlerSelectors.basePackage("com.ruoyi"))
                    //加了ApiOperation注解的类，才生成接口文档
                    .apis(RequestHandlerSelectors.withClassAnnotation(RestController.class))
                    .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
                    .paths(PathSelectors.any())
                    .build();
            listableBeanFactory.registerSingleton("defaultDocket", docket);
            log.info("\nWeb starter --  添加了默认的swagger扫描路径：{}", "管理平台:com.ruoyi");

        }
    }

    private ApiInfo apiInfo(String title, String description) {
        String appName = environment.getProperty("spring.application.name");
        String sysName = environment.getProperty("app.name");
        if (StrUtil.isBlank(appName)) {
            appName = "The Application ";
        }

        if (StrUtil.isBlank(sysName)) {
            sysName = appName;
        }

        String port = environment.getProperty("server.port");
        if (StrUtil.isBlank(port)) {
            port = "8080";
        }
        return new ApiInfoBuilder()
                .title(sysName+ title + "  接口文档说明")
                .description(sysName+ title + description + " 的接口文档说明,请查看左边导航菜单")
                .termsOfServiceUrl("http://localhost:" + port + "/")
                .version("1.0")
                .contact(new Contact("nannar", "www.nannar.cn", "admin@nannar.cn"))
                .build();
    }

    /***
     * oauth2配置
     * 需要增加swagger授权回调地址
     * http://localhost:8888/webjars/springfox-swagger-ui/o2c.html
     * @return
     */
    @Bean
    SecurityScheme securityScheme() {
        return new ApiKey(AuthConstant.AUTHORIZATION_KEY, AuthConstant.AUTHORIZATION_KEY, "header");
    }
}
